/* 
 * Rug.Cmd part of Rugland Console Framework
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Copyright (C) 2008 Phill Tew. All rights reserved.
 * 
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Rug.Cmd.Colors
{
    /// <summary>
    /// Holds a dictionary of console color themes keyed by background color. 
    /// </summary>
    public sealed class ConsoleColorThemeDirectory
    {
        #region Private Members

        // Constant length of the theme lookup
        private const int Length = 32 * 16;
        // Raw bytes of the theme lookup
        private byte[] m_RawBytes = new byte[Length];

        #endregion

        #region Lookup Indexer

        /// <summary>
        /// Get console color theme for a given background color
        /// </summary>
        /// <param name="background">the background color to use as the key to lookup the correct theme</param>
        /// <returns>the console color them for the background color</returns>
        public ConsoleColorTheme this[ConsoleColor background]
        {
            get 
            {
                ConsoleColorTheme theme = new ConsoleColorTheme();

                int index = ((int)background) * 32;

                for (int i = 0; i < 32; i++)
                {
                    // load the color theme from the raw bytes
                    theme.Mappings[i] = (ConsoleColorExt)m_RawBytes[index++];
                }

                return theme; 
            }
            set 
            {
                int index = ((int)background) * 32;

                for (int i = 0; i < 32; i++)
                {
                    // write the colors into the raw bytes
                    m_RawBytes[index++] = (byte)value.Mappings[i];
                }
            }
        }

        #endregion 

        #region Read

        /// <summary>
        /// Read a lookup from a file path
        /// </summary>
        /// <param name="path">the file path to read from</param>
        /// <returns>a lookup of console color themes keyed by background color</returns>
        public static ConsoleColorThemeDirectory Read(string path)
        {
            FileInfo info = new FileInfo(path);

            if (!info.Exists)
            {
                throw new Exception("");
            }

            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                return Read(stream);
            }
        }

        /// <summary>
        /// Read a lookup from a stream 
        /// </summary>
        /// <param name="stream">the stream containing the lookup</param>
        /// <returns>a lookup of console color themes keyed by background color</returns>
        public static ConsoleColorThemeDirectory Read(Stream stream)
        {
            ConsoleColorThemeDirectory themes = new ConsoleColorThemeDirectory();

            if (stream.Length == Length)
            {
                stream.Read(themes.m_RawBytes, 0, Length);
            }

            return themes;
        }

        #endregion

        #region Write

        /// <summary>
        /// Write the lookup to a file
        /// </summary>
        /// <param name="path">the path to write too</param>
        public void Write(string path)
        {
            FileInfo info = new FileInfo(path);

            if (info.Exists)
            {
                info.Delete();
            }

            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                Write(stream);
            }
        }

        /// <summary>
        /// Write the lookup to a stream
        /// </summary>
        /// <param name="stream">a stream to write to</param>
        public void Write(Stream stream)
        {
            stream.Write(m_RawBytes, 0, Length);
        }

        #endregion
    }
}
